[...slug].vue 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883
  1. <template>
  2. <div>
  3. <SldHomeTopSearch />
  4. <NavCatHeader />
  5. <div class="bottom_line"></div>
  6. <div class="goods_list_container self_background">
  7. <!-- 分类路径 -->
  8. <div class="level_nav_main">
  9. <div class="level_item" v-if="catePathName.path.length">
  10. <!-- 一级分类,显示该部分 -->
  11. <template v-if="1 === showIndex">
  12. <div class="level_nav_item">
  13. <a class="level_link">{{ catePathName.path[0] }}</a>
  14. </div>
  15. <!-- <i class="level-right"></i> -->
  16. <div class="level_nav_item">
  17. <div class="menu_drop">
  18. <div :class="{ trigger: true, hasChild: cate1.cate.length }">
  19. <span class="trigger_name">{{L['全部分类']}}</span>
  20. <i class="menu_drop_arrow"></i>
  21. </div>
  22. <div class="menu_drop_main" v-if="cate1.cate.length">
  23. <ul class="menu_drop_list">
  24. <li
  25. v-for="(
  26. { categoryName, categoryId, grade, pid }, index
  27. ) in cate1.cate"
  28. :key="index"
  29. >
  30. <router-link
  31. :to="'/goods/list/'+ calcProductName(categoryName) +'_v-'+ categoryId + '_gid-' + grade + '_pid-' + pid"
  32. >
  33. {{ categoryName }}</router-link
  34. >
  35. </li>
  36. </ul>
  37. </div>
  38. </div>
  39. </div>
  40. </template>
  41. <!-- 进入二级分类路径下的页面时,显示该部分 -->
  42. <template v-else-if="2 === showIndex">
  43. <div class="level_nav_item">
  44. <div class="menu_drop">
  45. <div :class="{ trigger: true, hasChild: cate1.cate.length }">
  46. <span class="trigger_name">{{ catePathName.path[0] }}</span>
  47. <i class="menu_drop_arrow"></i>
  48. </div>
  49. <div class="menu_drop_main" v-if="cate1.cate.length">
  50. <ul class="menu_drop_list">
  51. <li
  52. v-for="(
  53. { categoryName, categoryId, grade, pid }, index
  54. ) in cate1.cate"
  55. :key="index"
  56. >
  57. <router-link :to="'/goods/list/'+ calcProductName(categoryName) +'_v-'+ categoryId + '_gid-' + grade + '_pid-' + pid">
  58. {{ categoryName }}</router-link>
  59. </li>
  60. </ul>
  61. </div>
  62. </div>
  63. </div>
  64. <i class="level-right"></i>
  65. <div class="level_nav_item">
  66. <div class="menu_drop">
  67. <div :class="{ trigger: true, hasChild: cate2.cate.length }">
  68. <span class="trigger_name">{{ catePathName.path[1] }}</span>
  69. <i class="menu_drop_arrow"></i>
  70. </div>
  71. <div class="menu_drop_main" v-if="cate2.cate.length">
  72. <ul class="menu_drop_list">
  73. <li v-for="(item2, index) in cate2.cate" :key="index">
  74. <Nuxt-link :to="'/goods/list/'+ calcProductName(item2.categoryName) +'_v-'+ item2.categoryId + '_gid-' + item2.grade + '_pid-' + item2.pid" >
  75. {{ item2.categoryName }}
  76. </Nuxt-link>
  77. </li>
  78. </ul>
  79. </div>
  80. </div>
  81. </div>
  82. </template>
  83. <!-- 进入三级分类路径下的页面时,显示该部分 -->
  84. <template v-else>
  85. <div style="float: left">
  86. <div class="level_nav_item">
  87. <div class="menu_drop">
  88. <div :class="{ trigger: true, hasChild: cate1.cate.length }">
  89. <span class="trigger_name">{{ catePathName.path[0] }}</span>
  90. <i class="menu_drop_arrow"></i>
  91. </div>
  92. <div class="menu_drop_main" v-if="cate1.cate.length">
  93. <ul class="menu_drop_list">
  94. <li
  95. v-for="(
  96. { categoryName, categoryId, grade, pid }, index
  97. ) in cate1.cate"
  98. :key="index"
  99. >
  100. <Nuxt-link :to="'/goods/list/'+ calcProductName(categoryName) +'_v-'+ categoryId + '_gid-' + grade + '_pid-' + pid" >
  101. {{ categoryName }}
  102. </Nuxt-link>
  103. </li>
  104. </ul>
  105. </div>
  106. </div>
  107. </div>
  108. <i class="level-right"></i>
  109. <div class="level_nav_item">
  110. <div class="menu_drop">
  111. <div :class="{ trigger: true, hasChild: cate2.cate.length }">
  112. <span class="trigger_name">{{ catePathName.path[1] }}</span>
  113. <i class="menu_drop_arrow"></i>
  114. </div>
  115. <div class="menu_drop_main" v-if="cate2.cate.length">
  116. <ul class="menu_drop_list">
  117. <li
  118. v-for="(
  119. { categoryName, categoryId, grade, pid }, index
  120. ) in cate2.cate"
  121. :key="index"
  122. >
  123. <Nuxt-link :to="'/goods/list/'+ calcProductName(categoryName) +'_v-'+ categoryId + '_gid-' + grade + '_pid-' + pid" >
  124. {{ categoryName }}
  125. </Nuxt-link>
  126. </li>
  127. </ul>
  128. </div>
  129. </div>
  130. </div>
  131. <i class="level-right"></i>
  132. <div class="level_nav_item">
  133. <div class="menu_drop">
  134. <div :class="{ trigger: true, hasChild: cate3.cate.length }">
  135. <span class="trigger_name">{{ catePathName.path[2] }}</span>
  136. <i class="menu_drop_arrow"></i>
  137. </div>
  138. <div class="menu_drop_main" v-if="cate3.cate.length">
  139. <ul class="menu_drop_list">
  140. <li v-for="(item3, index) in cate3.cate" :key="index">
  141. <Nuxt-link :to="'/goods/list/'+ calcProductName(item3.categoryName) +'_v-'+ item3.categoryId + '_gid-' + item3.grade + '_pid-' + item3.pid" >
  142. {{ item3.categoryName }}
  143. </Nuxt-link>
  144. </li>
  145. </ul>
  146. </div>
  147. </div>
  148. </div>
  149. </div>
  150. </template>
  151. <div class="level_nav_item" style="margin-left: 10px">
  152. <div class="menu_drop" v-for="(item, index) in attriListTemp" :key="index">
  153. <div class="trigger label">
  154. <span class="trigger_name"
  155. >{{ item.name }}:&nbsp;<span color="#e2231a">{{ item.value }}</span>
  156. </span>
  157. <span @click="attriKick(index, item)">
  158. <i class="el-icon-close"></i>
  159. </span>
  160. </div>
  161. </div>
  162. </div>
  163. </div>
  164. <div class="level_item" v-show="keyword">
  165. <div class="level_nav_item" style="font-size: 13px">
  166. <a class="level_link"
  167. ><i style="color: #e22319">"{{ keyword }}" &nbsp;</i>{{L['搜索结果']}}</a
  168. >
  169. </div>
  170. </div>
  171. </div>
  172. <div class="goods_list_banner">
  173. <!-- 二级分类或者三级分类的组件 -->
  174. <GoodsListCate2
  175. :cateItem="cate1.child"
  176. :cate2Name="catePathName.path[0]"
  177. v-if="showIndex === 1"
  178. >
  179. </GoodsListCate2>
  180. <GoodsListCate2
  181. :cateItem="cate2.child"
  182. :cate2Name="catePathName.path[1]"
  183. v-if="showIndex === 2"
  184. >
  185. </GoodsListCate2>
  186. <GoodsListCate3
  187. :categoryid="categoryId3"
  188. :pid="Pids"
  189. v-if="showIndex === 3"
  190. @attriOption="attriOption"
  191. @brandOption="brandOption"
  192. ref="goodsCate3"
  193. ></GoodsListCate3>
  194. </div>
  195. <div class="goods_list clearfix">
  196. <!-- 筛选区域 -->
  197. <div class="sld_screen">
  198. <a @click="filterSort(0)" :class="0 == indexNum ? 'btn_sort' : ''">{{
  199. L["综合"]
  200. }}</a>
  201. <div class="goods_type">
  202. {{ L["商品类型"] }}:
  203. <p style="cursor: pointer">
  204. <input
  205. type="checkbox"
  206. :value="isOwnShop"
  207. id="isOwn"
  208. @input="filterStoreSelf(isOwnShop)"
  209. />
  210. <label for="isOwn" style="cursor: pointer">{{ L["仅平台自营"] }}</label>
  211. </p>
  212. </div>
  213. <span class="sld_goods_num">{{ goodsData.page.total }}{{ L["件相关商品"] }}</span>
  214. </div>
  215. <!-- 商品列表 -->
  216. <ul :class="{ sld_goods_list: true, skeleton_sld_goods_list: firstLoading }">
  217. <li
  218. v-for="(
  219. {
  220. goodsDefaultName,
  221. goodsName,
  222. goodsImage,
  223. goodsPrice,
  224. goodsMoney,
  225. saleNum,
  226. activityList,
  227. isFollowGoods,
  228. defaultProductId,
  229. storeName,
  230. isOwnShop,
  231. goodsId,
  232. storeId,
  233. },
  234. index
  235. ) in firstLoading ? skeletonData.data : goodsData.data"
  236. :key="index"
  237. >
  238. <div>
  239. <div class="sld_img sld_img_center">
  240. <router-link
  241. target="_blank"
  242. :to="'/goods/detail/'+ calcProductName(goodsDefaultName) +'_'+ defaultProductId"
  243. >
  244. <img :src="goodsImage" alt="" />
  245. </router-link>
  246. </div>
  247. <div class="sld_h32_hide">
  248. <router-link
  249. class="sld_goods_name"
  250. target="_blank"
  251. :to="'/goods/detail/'+ calcProductName(goodsDefaultName) +'_'+ defaultProductId"
  252. >
  253. <span v-html="goodsName"></span>
  254. </router-link>
  255. </div>
  256. <p class="clearfix">
  257. <span class="sld_goods_price fl"><em>{{ goodsMoney == null ? 'Contact us to give you an individual quote' : goodsMoney}}</em></span>
  258. </p>
  259. <div class="sld_vendor_name">
  260. <router-link
  261. target="_blank"
  262. :to="'/store/'+ calcProductName(storeName) +'_'+ storeId"
  263. class="sld_vendor_name"
  264. @click.stop
  265. >
  266. <span>{{ storeName }}</span>
  267. <span class="el-icon-arrow-right"></span>
  268. </router-link>
  269. </div>
  270. <div class="tag flex_row_start_center">
  271. <div class="is_own" v-if="isOwnShop == 1">{{L['自营']}}</div>
  272. <div v-if="isOwnShop == 2" style="height:18px;"></div>
  273. <div
  274. class="tag_b"
  275. :class="{ tag_b_pre_sale: promotionType == 103 }"
  276. v-for="({ promotionName, promotionType }, index) in activityList"
  277. :key="index"
  278. >
  279. {{ promotionName }}
  280. </div>
  281. </div>
  282. <div class="op_but flex_row_start_center">
  283. <div
  284. class="but_i first flex_row_center_center"
  285. @click.stop="collectGoods(defaultProductId, isFollowGoods)"
  286. >
  287. <div v-if="!isFollowGoods">
  288. <i class="iconfont">&#xe612;</i>{{ L["收藏"] }}
  289. </div>
  290. <div v-else>
  291. <i><img src="/goods/collection.png" class="collection" /></i
  292. >{{ L["已收藏"] }}
  293. </div>
  294. </div>
  295. <div
  296. class="but_i second flex_row_center_center"
  297. @click.stop="addEnquiry(defaultProductId, goodsId)"
  298. >
  299. <div>
  300. <i
  301. ><img
  302. src="/email.svg"
  303. alt=""
  304. width="22"
  305. height="21" /></i
  306. >{{ L["发送询盘"] }}
  307. </div>
  308. </div>
  309. </div>
  310. </div>
  311. </li>
  312. </ul>
  313. <SldCommonEmpty v-show="isEmpty" />
  314. </div>
  315. <!-- 分页 -->
  316. <div class="flex_row_center_center sld_pagination">
  317. <el-pagination
  318. @current-change="handleCurrentChange"
  319. v-model:currentPage.sync="pagitionCurrent"
  320. :page-size="goodsData.page.pageSize"
  321. layout="prev, pager, next"
  322. :total="goodsData.page.total"
  323. :hide-on-single-page="true"
  324. >
  325. </el-pagination>
  326. </div>
  327. <EnquiryModal
  328. v-if="enquiryVis"
  329. :itemType="'GOODS'"
  330. :itemId="productId"
  331. @closeLoingModal="closeEnquiryModal"
  332. />
  333. <SldLoginModal
  334. v-if="loginModalVisibleFlag"
  335. @closeLoingModal="closeLoingModal"
  336. />
  337. </div>
  338. </div>
  339. </template>
  340. <script setup>
  341. import { getCurrentInstance, onMounted, reactive, ref, watchEffect, watch } from "vue";
  342. import { ElMessage,ElPagination } from "element-plus";
  343. import { getCurLanguage } from '@/composables/common.js';
  344. import { useFiltersStore } from "@/store/filter.js";
  345. const filtersStore = useFiltersStore();
  346. const proxy = getCurrentInstance();
  347. const L = getCurLanguage();
  348. const enquiryVis = ref(false);
  349. const productId = ref();
  350. //变量------------------------------
  351. const firstLoading = ref(true); //是否第一次加载
  352. const skeletonData = reactive({ data: [] });
  353. const loginModalVisibleFlag = ref(false); //登录弹框是否显示,默认不显示
  354. const initSkeletonData = () => {
  355. for (let i = 0; i < 10; i++) {
  356. skeletonData.data.push({
  357. goodsDefaultName:"",
  358. goodsName: "",
  359. goodsImage: "",
  360. goodsPrice: "",
  361. goodsMoney:"",
  362. saleNum: "",
  363. activityList: "",
  364. isFollowGoods: "",
  365. defaultProductId: "",
  366. });
  367. }
  368. };
  369. initSkeletonData();
  370. const route = useRoute();
  371. const router = useRouter();
  372. const catePath = ref([]); //导航路径
  373. const showIndex = ref(0); //显示flag
  374. const catePathName = reactive({ path: [] }); //需要在页面显示的整个分类路径
  375. const params = reactive({current: 1});//初始化的请求参数
  376. const goodsData = reactive({ data: [], page: {} });
  377. const indexNum = ref(0);
  378. const lowprice = ref(null);
  379. const highprice = ref(null);
  380. const isEmpty = ref(false);
  381. const cate1 = reactive({ cate: {}, child: {} });
  382. const cate2 = reactive({ cate: {}, child: {} });
  383. const cate3 = reactive({ cate: {} });
  384. const categoryId3 = ref( calcUrlShopId(route.path)? calcUrlShopId(route.path) : '');
  385. const attriList = ref([]);
  386. const attriListTemp = ref([]);
  387. const scrollTop = ref(null);
  388. const priceDidSel = ref(false);
  389. const storeData = reactive({ cat: [] }); //店铺数据,cat:店铺分类,goods:店铺商品列表
  390. const routeParams = reactive({ data: {} })
  391. const pagitionCurrent = ref(1)
  392. const categoryName = ref(calcMallUrlCatName(route.path))
  393. const categoryIds = ref(calcUrlShopId(route.path))
  394. const Gids = ref(calcMallUrlGid(route.path))
  395. const Pids = ref(calcMallUrlPid(route.path))
  396. const cur = ref(calcMallUrlCur(route.path))
  397. const keyword = ref(calcMallUrlKeyword(route.path))
  398. const brand = ref(calcMallUrlBrand(route.path))
  399. //方法------------------------------
  400. const clacRouteParams = () => {
  401. let arr = route.params.slug
  402. let newArr = {}
  403. for(let i in arr){
  404. newArr[arr[i].toString().split('-')[0]] = arr[i].toString().split('-')[1]
  405. }
  406. routeParams.data = newArr
  407. console.log('routeParams',route.path)
  408. if (categoryIds.value) {
  409. params.categoryIds = categoryIds.value
  410. }
  411. if (cur.value) {
  412. params.current = cur.value;
  413. }
  414. if (keyword.value) {
  415. params.keyword = keyword.value;
  416. }
  417. if (routeParams.data.storeId) {
  418. params.storeId = routeParams.data.storeId;
  419. }
  420. if (brand.value) {
  421. params.brandIds = brand.value;
  422. }
  423. getInitData(params);
  424. }
  425. const addEnquiry = (pid,gid) => {
  426. productId.value = pid
  427. enquiryVis.value = true;
  428. };
  429. //关闭登录弹框
  430. const closeEnquiryModal = () => {
  431. enquiryVis.value = false;
  432. };
  433. //初始化数据,进行请求-start
  434. const getInitData = async (params) => {
  435. if (process.client) {
  436. window.scrollTo(0, scrollTop.value);
  437. }
  438. let searchParams = { ...params };
  439. let keys = ''
  440. if(searchParams.categoryIds){
  441. keys += searchParams.categoryIds
  442. }
  443. if(searchParams.keyword){
  444. keys += searchParams.keyword
  445. }
  446. if(searchParams.current){
  447. keys += searchParams.current
  448. }
  449. if(searchParams.isSelf){
  450. keys += searchParams.isSelf
  451. }
  452. if(searchParams.brandIds){
  453. keys += searchParams.brandIds
  454. }
  455. const { data: value, pending: pending } = await useFetchRaw(
  456. apiUrl + "v3/goods/front/goods/goodsList",
  457. {
  458. params: searchParams,
  459. key:keys.toString(),
  460. headers:{Authorization:'Bearer ' + filtersStore.getToken}
  461. }
  462. );
  463. const res = value._rawValue;
  464. if (!pending._rawValue) {
  465. firstLoading.value = false;
  466. }
  467. if (res.state == 200) {
  468. goodsData.data = res.data.list;
  469. isEmpty.value = res.data.list.length ? false : true;
  470. goodsData.page = res.data.pagination;
  471. showIndex.value = Number(Gids.value);
  472. if (categoryIds.value && Gids.value && Pids.value) {
  473. cateForm(categoryIds.value, Gids.value);
  474. }
  475. }
  476. };
  477. //初始化数据,进行请求-end
  478. const SEOinfo = reactive({
  479. seoTitle: "Goods List",
  480. seoDesc: "",
  481. seoKeywords: "",
  482. });
  483. //根据切换数据,改变SEO
  484. const setSEO = () => {
  485. for (let i in storeData.cat) {
  486. if (storeData.cat[i].categoryId == route.query.categoryId) {
  487. SEOinfo.seoTitle = storeData.cat[i].seoInfo.seoTitle;
  488. SEOinfo.seoDesc = storeData.cat[i].seoInfo.seoDesc;
  489. SEOinfo.seoKeywords = storeData.cat[i].seoInfo.seoKeywords;
  490. break;
  491. }else{
  492. for(let j in storeData.cat[i].children){
  493. if(storeData.cat[i].children[j].categoryId == route.query.categoryId){
  494. SEOinfo.seoTitle = storeData.cat[i].children[j].seoInfo.seoTitle;
  495. SEOinfo.seoDesc = storeData.cat[i].children[j].seoInfo.seoDesc;
  496. SEOinfo.seoKeywords = storeData.cat[i].children[j].seoInfo.seoKeywords;
  497. }
  498. }
  499. }
  500. }
  501. useHead({
  502. title: SEOinfo.seoTitle,
  503. meta: [
  504. {
  505. name: "description",
  506. content: SEOinfo.seoDesc,
  507. },
  508. {
  509. name: "keywords",
  510. content: SEOinfo.seoKeywords,
  511. },
  512. ],
  513. });
  514. };
  515. const cateForm = (c, g) => {
  516. if (g == 0) {
  517. return false;
  518. }
  519. if (g == 3) {
  520. let pid = Pids.value
  521. cateForm(pid, 2);
  522. return false;
  523. }
  524. let param = {
  525. categoryId: c,
  526. grade: g,
  527. };
  528. console.log(param)
  529. let cateId = categoryIds.value;
  530. get("v3/goods/front/goods/category/listByPId", param).then((res) => {
  531. if (res.state == 200) {
  532. storeData.cat = res.data;
  533. switch (Number(g)) {
  534. case 1: {
  535. let cdx1 = res.data.findIndex(i => i.categoryId == c)
  536. cate1.cate = res.data.filter(i => i.categoryId != c)
  537. cate1.child = res.data[cdx1].children
  538. catePathName.path[0] = res.data[cdx1].categoryName
  539. if (Gids.value == 2 || Gids.value == 3) {
  540. cate2.cate = cate1.child.filter(i => i.categoryId != cateId)
  541. }
  542. break;
  543. }
  544. case 2: {
  545. cate2.child = res.data[0].children
  546. catePathName.path[1] = res.data[0].categoryName
  547. if (Gids.value == 3) {
  548. let cdx3 = cate2.child.findIndex(i => i.categoryId == cateId)
  549. cate3.cate = cate2.child.filter(i => i.categoryId != cateId)
  550. catePathName.path[2] = cate2.child[cdx3].categoryName
  551. }
  552. let cate2Pid = res.data[0].pid
  553. cateForm(cate2Pid, 1)
  554. break;
  555. }
  556. }
  557. setSEO();
  558. }
  559. });
  560. };
  561. const categorySearch = (data, val) => {
  562. //遍历分类列表,找到该categoryId所在的id路径
  563. for (var i = 0; i < data.length; i++) {
  564. if (data[i] && data[i].categoryId == val) {
  565. return [
  566. {
  567. categoryId: val,
  568. categoryName: data[i].categoryName,
  569. children: data[i].children,
  570. },
  571. ];
  572. }
  573. if (data[i] && data[i].children) {
  574. var d = categorySearch(data[i].children, val);
  575. if (d)
  576. return d.concat({
  577. categoryId: data[i].categoryId,
  578. categoryName: data[i].categoryName,
  579. children: data[i].children,
  580. });
  581. }
  582. }
  583. };
  584. //获取分类Id数组对应的分类名--end
  585. //页数改变的方法-start
  586. const handleCurrentChange = (e) => {
  587. let path = ''
  588. if(!calcMallUrlCur(route.path)){
  589. path = route.path+'_cur-'+e
  590. }else{
  591. let arr = route.path.split('_')
  592. arr.pop()
  593. path = arr.join('_')+'_cur-'+e
  594. }
  595. router.push({
  596. path:path
  597. });
  598. //getInitData(params);
  599. };
  600. const filterSort = (index) => {
  601. if (indexNum.value == index) {
  602. return;
  603. }
  604. indexNum.value = index;
  605. params.current = 1;
  606. scrollTop.value = document.body.scrollTop || document.documentElement.scrollTop;
  607. let query = {};
  608. if (route.query.categoryId) {
  609. query.categoryId = route.query.categoryId;
  610. } else if (route.query.keyword) {
  611. query.keyword = route.query.keyword;
  612. } else if (route.query.storeId) {
  613. query.storeId = route.query.storeId;
  614. }
  615. if (route.query.goodsIds) {
  616. query.goodsIds = route.query.goodsIds;
  617. }
  618. if (route.query.brandId) {
  619. query.brandId = route.query.brandId;
  620. }
  621. router.push({
  622. path: "list",
  623. query: {
  624. ...query,
  625. sort: indexNum.value,
  626. },
  627. });
  628. };
  629. //页数改变的方法-end
  630. //商品是否自营-start
  631. const isOwnShop = ref(false);
  632. const filterStoreSelf = (e) => {
  633. isOwnShop.value = !e;
  634. params.isSelf = isOwnShop.value ? 1 : 0;
  635. getInitData(params);
  636. };
  637. //商品是否自营-end
  638. //收藏及取消收藏商品
  639. const collectGoods = (defaultProductId, isFollowGoods) => {
  640. if (filtersStore.getLoginFlag) {
  641. //已登录
  642. let params = {
  643. productIds: defaultProductId,
  644. isCollect: !isFollowGoods,
  645. };
  646. post("v3/member/front/followProduct/edit", params).then((res) => {
  647. if (res.state == 200) {
  648. ElMessage.success(res.msg);
  649. goodsData.data.map((goodsItem) => {
  650. if (goodsItem.defaultProductId == defaultProductId) {
  651. goodsItem.isFollowGoods = !isFollowGoods;
  652. }
  653. });
  654. } else {
  655. ElMessage.error(res.msg);
  656. }
  657. });
  658. } else {
  659. //未登录提示登录
  660. loginModalVisibleFlag.value = true;
  661. }
  662. };
  663. //关闭登录弹框
  664. const closeLoingModal = () => {
  665. loginModalVisibleFlag.value = false;
  666. };
  667. //属性选择--start
  668. const attriOption = (attributeName, attributeValue, attributeId, attributeValueId) => {
  669. attriList.value.push(attributeValueId)
  670. attriListTemp.value.push({
  671. name: attributeName,
  672. value: attributeValue,
  673. type: 'attr',
  674. id: attributeId,
  675. valueId: attributeValueId
  676. })
  677. params.attributeInfo = attriList.value.join(',')
  678. get('v3/goods/front/goods/goodsList', params).then(res => {
  679. if (res.state == 200) {
  680. goodsData.data = res.data.list
  681. goodsData.page = res.data.pagination
  682. }
  683. })
  684. };
  685. const goodsCate3 = ref(null); //获取dom的ref,名字同名
  686. const attriKick = (index, item) => {
  687. attriListTemp.value.splice(index, 1)
  688. if (item.type == "attr") {
  689. attriList.value = attriList.value.filter(subitem => subitem != item.valueId)
  690. proxy.refs.goodsCate3.attrSorH(item.id);
  691. if (attriListTemp.value.length) {
  692. params.attributeInfo = attriList.value.join(',')
  693. get('v3/goods/front/goods/goodsList', params).then(res => {
  694. if (res.state == 200) {
  695. goodsData.data = res.data.list
  696. goodsData.page = res.data.pagination
  697. }
  698. })
  699. } else {
  700. delete params.attributeInfo
  701. get('v3/goods/front/goods/goodsList', params).then(res => {
  702. if (res.state == 200) {
  703. goodsData.data = res.data.list
  704. goodsData.page = res.data.pagination
  705. }
  706. })
  707. }
  708. } else if (item.type == "brand") {
  709. delete params.brandIds
  710. proxy.refs.goodsCate3.brandSorH()
  711. get('v3/goods/front/goods/goodsList', params).then(res => {
  712. if (res.state == 200) {
  713. goodsData.data = res.data.list
  714. goodsData.page = res.data.pagination
  715. }
  716. })
  717. }
  718. };
  719. const brandOption = (brandId, brandName) => {
  720. attriListTemp.value.push({
  721. name: '品牌',
  722. value: brandName,
  723. type: 'brand',
  724. })
  725. params.brandIds = brandId
  726. get('v3/goods/front/goods/goodsList', params).then(res => {
  727. goodsData.data = res.data.list
  728. goodsData.page = res.data.pagination
  729. })
  730. };
  731. //属性选择--end
  732. //监听事件--start
  733. watchEffect(() => {
  734. if (routeParams.data.keyword != undefined) {
  735. // keyword.value = routeParams.data.keyword;
  736. // categoryId3.value = "";
  737. // showIndex.value = -1;
  738. // catePathName.path = [];
  739. // params.keyword = keyword.value;
  740. // delete params.categoryIds;
  741. // getInitData(params);
  742. // useHead({
  743. // title: keyword.value,
  744. // });
  745. } else if (categoryIds) {
  746. categoryId3.value = categoryIds.value;
  747. // keyword.value = "";
  748. // params.categoryIds = categoryIds;
  749. // delete params.keyword;
  750. // getInitData(params);
  751. }
  752. });
  753. watch(
  754. () => params.current,
  755. (nv, ov) => {
  756. if (nv != ov) {
  757. pagitionCurrent.value = Number(nv)
  758. }
  759. }
  760. );
  761. watch(
  762. () => categoryIds.value,
  763. (nv, ov) => {
  764. if (nv != ov) {
  765. categoryId3.value = nv;
  766. attriList.value = [];
  767. attriListTemp.value = [];
  768. isOwnShop.value = false;
  769. }
  770. }
  771. );
  772. watch(
  773. () => keyword.value,
  774. (nv, ov) => {
  775. if (nv != ov) {
  776. lowprice.value = highprice.value = null;
  777. isOwnShop.value = false;
  778. }
  779. }
  780. );
  781. //监听事件--end
  782. router.beforeEach((to, from) => {
  783. if (to.path == from.path) {
  784. document.body.scrollTop = scrollTop.value;
  785. }
  786. });
  787. onMounted(() => {
  788. setTimeout(() => {
  789. sldStatEvent({ behaviorType: 'pv',pageUrl: defaultUrl + router.currentRoute.value.path, referrerPageUrl: apiUrl });
  790. }, 3000)
  791. nextTick(() => {
  792. clacRouteParams()
  793. });
  794. });
  795. //返回值
  796. </script>
  797. <style lang="scss" scoped>
  798. @import "@/assets/style/goodsList.scss";
  799. @import "@/assets/style/base.scss";
  800. input[type="checkbox"] {
  801. display: none;
  802. vertical-align: middle;
  803. margin-bottom: 3px;
  804. margin-right: 3px;
  805. }
  806. input[type="checkbox"] + label {
  807. background: url("/goods/unsel.png") left center no-repeat;
  808. padding-left: 20px;
  809. background-size: 12px 12px;
  810. }
  811. input[type="checkbox"]:checked + label {
  812. background-image: url("/goods/select.png");
  813. }
  814. .empty_page {
  815. flex-direction: column;
  816. padding: 100px;
  817. }
  818. .sld_pagination {
  819. padding: 30px 0;
  820. }
  821. /*添加css样式*/
  822. input::-webkit-outer-spin-button,
  823. input::-webkit-inner-spin-button {
  824. -webkit-appearance: none;
  825. }
  826. input[type="number"] {
  827. -moz-appearance: textfield;
  828. }
  829. </style>